﻿using System;
using System.Management;
using System.Security.Cryptography;
using System.Text;

namespace FrameWork
{
   public static class FingerPrint
   {
        private static string _fingerPrint = string.Empty;
       public static string IdentificationCode
       {
            get
            {
                if (!string.IsNullOrEmpty(_fingerPrint)) return _fingerPrint;

                _fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " + biosId() + "\nBASE >> " + baseId() + "\nDISK >> " + diskId() + "\nVIDEO >> " + videoId() + "\nMAC >> " + macId());
                return _fingerPrint;
            }
        }
        private static string GetHash(string s)
        {
            var hash = "";
            try
            {
                MD5 sec = new MD5CryptoServiceProvider();
                var enc = new ASCIIEncoding();
                var bt = enc.GetBytes(s);
                hash = GetHexString(sec.ComputeHash(bt));
            }
            catch (Exception ex)
            {
                Log4Help.Error("加密错误!!", ex);
            }
            return hash;
        }
        private static string GetHexString(byte[] bt)
        {
            var s = string.Empty;
            for (var i = 0; i < bt.Length; i++)
            {
                var b = bt[i];
                int n, n1, n2;
                n = b;
                n1 = n & 15;
                n2 = (n >> 4) & 15;
                if (n2 > 9)
                    s += ((char)(n2 - 10 + 'A')).ToString();
                else
                    s += n2.ToString();
                if (n1 > 9)
                    s += ((char)(n1 - 10 + 'A')).ToString();
                else
                    s += n1.ToString();
                if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-";
            }
            return s;
        }
        #region Original Device ID Getting Code
        //Return a hardware identifier
        private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue)
        {
            var result = "";
            try
            {
                var mc = new ManagementClass(wmiClass);
                var moc = mc.GetInstances();
                foreach (var o in moc)
                {
                    if (!string.IsNullOrWhiteSpace(result)) break;

                    try
                    {
                        if (o[wmiMustBeTrue].ToString() != "True") continue;

                        result = o[wmiProperty].ToString();
                        break;
                    }
                    catch
                    {
                        // ignored
                    }
                }
            }
            catch (Exception ex)
            {
                Log4Help.Error("机器码错误!!", ex);
            }
            return result;
        }
        //Return a hardware identifier
        private static string identifier(string wmiClass, string wmiProperty)
        {
            var result = "";
            try
            {
                var mc = new ManagementClass(wmiClass);
                var moc = mc.GetInstances();
                foreach (var o in moc)
                {
                    if (!string.IsNullOrWhiteSpace(result)) break;

                    try
                    {
                        result = o[wmiProperty].ToString();
                        break;
                    }
                    catch
                    {
                        // ignored
                    }
                }
            }
            catch (Exception ex)
            {
                Log4Help.Error("机器码错误!!", ex);
            }
            return result;
        }
        private static string cpuId()
        {
            var retVal = identifier("Win32_Processor", "UniqueId");
            if (retVal == "") //If no UniqueID, use ProcessorID
            {
                retVal = identifier("Win32_Processor", "ProcessorId");
                if (retVal == "") //If no ProcessorId, use Name
                {
                    retVal = identifier("Win32_Processor", "Name");
                    if (retVal == "") //If no Name, use Manufacturer
                    {
                        retVal = identifier("Win32_Processor", "Manufacturer");
                    }
                    //Add clock speed for extra security
                    retVal += identifier("Win32_Processor", "MaxClockSpeed");
                }
            }
            return retVal;
        }
        //BIOS Identifier
        private static string biosId()
        {
            return identifier("Win32_BIOS", "Manufacturer")
            + identifier("Win32_BIOS", "SMBIOSBIOSVersion")
            + identifier("Win32_BIOS", "IdentificationCode")
            + identifier("Win32_BIOS", "SerialNumber")
            + identifier("Win32_BIOS", "ReleaseDate")
            + identifier("Win32_BIOS", "Version");
        }
        //Main physical hard drive ID
        private static string diskId()
        {
            return identifier("Win32_DiskDrive", "Model")
            + identifier("Win32_DiskDrive", "Manufacturer")
            + identifier("Win32_DiskDrive", "Signature")
            + identifier("Win32_DiskDrive", "TotalHeads");
        }
        //Motherboard ID
        private static string baseId()
        {
            return identifier("Win32_BaseBoard", "Model")
            + identifier("Win32_BaseBoard", "Manufacturer")
            + identifier("Win32_BaseBoard", "Name")
            + identifier("Win32_BaseBoard", "SerialNumber");
        }
        //Primary video controller ID
        private static string videoId()
        {
            return identifier("Win32_VideoController", "DriverVersion")
            + identifier("Win32_VideoController", "Name");
        }
        //First enabled network card ID
        private static string macId()
        {
            return identifier("Win32_NetworkAdapterConfiguration",
                "MACAddress", "IPEnabled");
        }
        #endregion
    }

}
